I am trying to write a DXL that will automatically insert text at the cursor position. I am using the "getCursorPosition" function to see where to insert the text. However, this method falls apart when there is rich text formatting involved because when I extract the text, edit it, and then insert it back into the object, all of the RTF is stripped from the string. To solve this I have been trying to go through the rich text string to find the true cursor position but I have been unable to successfully determine which parts of the string is the RTF portion and which is the actual text. Is there an easy way to do this that I am missing? Is there a common method to parse RTF so that I can count the correct cursor pos? Any help is greatly appreciated. An example of a rich text string is below:
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Tahoma;}{\f1\fnil\fcharset2 Symbol;}}
\viewkind4\uc1\pard\f0\fs20 Comments blah blah\par
\pard{\pntext\f1\'B7\tab}{\*\pn\pnlvlblt\pnf1\pnindent0{\pntxtb\'B7}}Bullet no indent\par
\pard{\pntext\f1\'B7\tab}{\*\pn\pnlvlblt\pnf1\pnindent0{\pntxtb\'B7}}\li360 Bullet 1 indent\par
\pard{\pntext\f1\'B7\tab}{\*\pn\pnlvlblt\pnf1\pnindent0{\pntxtb\'B7}}\li720 Bullet 2 indent\par
}
Thank you, steaksauce - Fri Jan 03 14:00:44 EST 2014 |
Re: Finding Cursor Position in Rich Text Well you might want to think again, if you really want to use the approach you are following. You could of course try to count the plain text characters to get to the position in the string, like so:
bool b = false
int x = getCursorPosition(current Module, b)
RichTextParagraph rp
RichText rt
int iPos = 0
for rp in richText (current Object)."Object Text" do {
if (rp.isBullet) iPos += 1
for rt in rp do {
int iLen = length rt.text
if (iPos + iLen >= x) {
string sText = rt.text
int ich = x - iPos
print "Found Text in paragraph: '" rt.text "' before character " sText[ich] "\n"
break
}
iPos += iLen
}
}
But still there are a couple of problems with your approach, because even if you were able to get the correct cursor position in the richtext (which I would test very thoroughly because it is possible that users paste stuff from word, you get inlined OLE etc. and you will not be able to catch all those problematic cases and your calculation will likely fail) you still would have to fight with at least the follwing problem:
So I would suggest a different approach. Make a DXL GUI window with a richText field, where you copy the current Object Text. In this window you have more possibilities, e.g. to read the current richtext contents. Perform your manipulation there. Give the user an apply button to be able to transfer the change to your attribute value. Disable editing on the GUI when the user is inplace editing the module. Use a sync trigger, to update your GUI with the current Object. Another possibility that I used successfully, was to do cut/paste in inplace editing from DXL to replace/reformat the currently selected text. So if you can make your tool just modify a selected text, then use cut to cut the selected text from the attribute value, perform your modifications and then paste it back. This works without the need of knowing the cursor position. Maybe that helps, regards, Mathias |
Re: Finding Cursor Position in Rich Text Mathias Mamsch - Sat Jan 04 14:33:53 EST 2014 Well you might want to think again, if you really want to use the approach you are following. You could of course try to count the plain text characters to get to the position in the string, like so:
bool b = false
int x = getCursorPosition(current Module, b)
RichTextParagraph rp
RichText rt
int iPos = 0
for rp in richText (current Object)."Object Text" do {
if (rp.isBullet) iPos += 1
for rt in rp do {
int iLen = length rt.text
if (iPos + iLen >= x) {
string sText = rt.text
int ich = x - iPos
print "Found Text in paragraph: '" rt.text "' before character " sText[ich] "\n"
break
}
iPos += iLen
}
}
But still there are a couple of problems with your approach, because even if you were able to get the correct cursor position in the richtext (which I would test very thoroughly because it is possible that users paste stuff from word, you get inlined OLE etc. and you will not be able to catch all those problematic cases and your calculation will likely fail) you still would have to fight with at least the follwing problem:
So I would suggest a different approach. Make a DXL GUI window with a richText field, where you copy the current Object Text. In this window you have more possibilities, e.g. to read the current richtext contents. Perform your manipulation there. Give the user an apply button to be able to transfer the change to your attribute value. Disable editing on the GUI when the user is inplace editing the module. Use a sync trigger, to update your GUI with the current Object. Another possibility that I used successfully, was to do cut/paste in inplace editing from DXL to replace/reformat the currently selected text. So if you can make your tool just modify a selected text, then use cut to cut the selected text from the attribute value, perform your modifications and then paste it back. This works without the need of knowing the cursor position. Maybe that helps, regards, Mathias
I work with the author who posted the question, so I'm following up while he is out of the office. The author's ultimate goal is to insert a DXL-calculated value at the cursor position in rich text. If a DXL GUI window with a richTextField is used, he would still want to place his cursor in the richTextField and then have a DXL-calculated value inserted at the cursor position. The users who would be using this GUI have no idea how to manipulate DXL nor how to format objects, so the GUI would have to be just push-button for them with no further manipulation required. So, the next question would be how does he insert a DXL-calculated value at the cursor position in a richTextField? Here would be simplified typical usage: The user selects an object (firstObject) and then places the cursor in firstObject's "Object Text" attribute where the DXL-calculated value is to be inserted (or in a ricTextField of a DXL GUI window). The author wanted to do this via DXL extracting the cursor position using getCursorPosition via in-place editing, but is open to the suggestion of using a DXL GUI window. Take the sample rich text "Object Text," below: "This is my formatted text and please refer to for more details." The user then places the cursor between the words "to" and "for" in the above and presses <Apply> in the DXL GUI. A pop-up then appears directing the user to next select a reference object (refObject) and then press another <Apply> button in the DXL GUI after selecting the reference object. If refObject is not a heading, then the DXL then places the word "object" and the value of attribute "Absolute Number" of refObject into the "Object Text" of firstObject at the cursor position. In the above text example, the resulting text would be:
"This is my formatted text and please refer to object 765 for more details."
However, if refObject is a heading, then the DXL would insert the word "section" and the value of the "Object Number" of refObject into the "Object Text" of firstObject at the cursor position. In the above text example, the resulting text would be:
"This is my formatted text and please refer to section 2.1.3 for more details."
The author has the above working fine for plain text, but hasn't figured out how to maintain the rich text formatting. Again, the users using this DXL know nothing about DXL (they use custom pull-down menus to select and execute DXLs) nor anything about text formatting, so this needs to be all push-button for them.
|
Re: Finding Cursor Position in Rich Text BeastBoysDad - Mon Jan 06 16:14:04 EST 2014
I work with the author who posted the question, so I'm following up while he is out of the office. The author's ultimate goal is to insert a DXL-calculated value at the cursor position in rich text. If a DXL GUI window with a richTextField is used, he would still want to place his cursor in the richTextField and then have a DXL-calculated value inserted at the cursor position. The users who would be using this GUI have no idea how to manipulate DXL nor how to format objects, so the GUI would have to be just push-button for them with no further manipulation required. So, the next question would be how does he insert a DXL-calculated value at the cursor position in a richTextField? Here would be simplified typical usage: The user selects an object (firstObject) and then places the cursor in firstObject's "Object Text" attribute where the DXL-calculated value is to be inserted (or in a ricTextField of a DXL GUI window). The author wanted to do this via DXL extracting the cursor position using getCursorPosition via in-place editing, but is open to the suggestion of using a DXL GUI window. Take the sample rich text "Object Text," below: "This is my formatted text and please refer to for more details." The user then places the cursor between the words "to" and "for" in the above and presses <Apply> in the DXL GUI. A pop-up then appears directing the user to next select a reference object (refObject) and then press another <Apply> button in the DXL GUI after selecting the reference object. If refObject is not a heading, then the DXL then places the word "object" and the value of attribute "Absolute Number" of refObject into the "Object Text" of firstObject at the cursor position. In the above text example, the resulting text would be:
"This is my formatted text and please refer to object 765 for more details."
However, if refObject is a heading, then the DXL would insert the word "section" and the value of the "Object Number" of refObject into the "Object Text" of firstObject at the cursor position. In the above text example, the resulting text would be:
"This is my formatted text and please refer to section 2.1.3 for more details."
The author has the above working fine for plain text, but hasn't figured out how to maintain the rich text formatting. Again, the users using this DXL know nothing about DXL (they use custom pull-down menus to select and execute DXLs) nor anything about text formatting, so this needs to be all push-button for them.
Well if your goal is only to insert a text, then just pasting something works usually fine. Example:
if (inplaceEditing current Module) {
setRichClip richText "{\\b xxx I just pasted Text} "
callStdItem_ clipPasteItem
} else {
ack "Please place the cursor somewher in an attribute text, before starting this tool!"
halt
}
See also this post: https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014212995&ps=25 Hope this helps, regards, Mathias |